package com.huawei.cloud.phone.management.domain.pkg;

import com.huawei.cloud.phone.management.common.exception.ApkInstallException;
import com.huawei.cloud.phone.management.common.exception.ApkPushException;
import com.huawei.cloud.phone.management.common.exception.ApkUninstallException;
import com.huawei.cloud.phone.management.common.utils.I18nUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@AllArgsConstructor
@Component
public class PkgDomainService {
    private final PkgGateway pkgGateway;

    /**
     * 安装应用
     *
     * @param phoneIds 需要安装应用的手机ID
     * @param pkgData  应用数据
     */
    public void installPkg(List<String> phoneIds, PkgData pkgData) {
        Optional<String> errorMsg = pkgGateway.pushFile(pkgData.getApkData());
        if (errorMsg.isPresent()) {
            throw new ApkPushException(errorMsg.get());
        }

        List<PkgResult> result = pkgGateway.installApk(phoneIds, pkgData.getApkData());
        if (!result.isEmpty()) {
            throw new ApkInstallException(genPhoneErrorMsg(result));
        }
    }

    /**
     * 安装应用
     *
     * @param serverPhoneIdMap 需要安装应用的服务器ID和手机ID
     * @param pkgData  应用数据
     */
    public void installSharePkg(Map<String, Set<String>> serverPhoneIdMap, PkgData pkgData) {
        Optional<String> errorMsg = pkgGateway.pushFile(pkgData.getApkData());
        if (errorMsg.isPresent()) {
            throw new ApkPushException(errorMsg.get());
        }

        String seekPhoneId = serverPhoneIdMap.entrySet().iterator().next().getValue().iterator().next();
        List<PkgResult> result = pkgGateway.installApk(Collections.singletonList(seekPhoneId), pkgData.getApkData());
        if (!result.isEmpty()) {
            throw new ApkInstallException(seekPhoneId, result.get(0).getErrorMsg());
        }

        Optional<PkgResult> pkgResult = pkgGateway.prepareTar(seekPhoneId, pkgData.getTarData());
        if (pkgResult.isPresent()) {
            throw new ApkPushException(pkgResult.get().getErrorMsg());
        }

        result = pkgGateway.uninstallApk(Collections.singletonList(seekPhoneId), pkgData.getTarData().getPkgName());
        if (!result.isEmpty()) {
            log.warn("uninstall apk failed from seek phone {}", seekPhoneId);
        }

        List<String> serverIds = new ArrayList<>(serverPhoneIdMap.keySet());
        List<PkgResult> pushServerResult = pkgGateway.pushShareTar(serverIds, pkgData.getTarData());

        if (pushServerResult.size() == serverIds.size()) {
            throw new ApkInstallException(genServerErrorMsg(result));
        }

        Set<String> failedServerIds = pushServerResult.stream().map(PkgResult::getId).collect(Collectors.toSet());
        List<String> phoneIds = serverPhoneIdMap.entrySet().stream()
                .filter(entry -> !failedServerIds.contains(entry.getKey()))
                .map(Map.Entry::getValue)
                .flatMap(Collection::stream)
                .collect(Collectors.toList());
        List<PkgResult> installPhoneResult = pkgGateway.installTar(phoneIds, pkgData.getTarData().getPkgName());

        if (!pushServerResult.isEmpty() && installPhoneResult.isEmpty()) {
            throw new ApkInstallException(genServerErrorMsg(pushServerResult));
        }
        if (!installPhoneResult.isEmpty() && pushServerResult.isEmpty()) {
            throw new ApkInstallException(genPhoneErrorMsg(installPhoneResult));
        }
        if (!pushServerResult.isEmpty()) {
            throw new ApkInstallException(genServerPhoneErrorMsg(pushServerResult, installPhoneResult));
        }
    }

    private String genServerErrorMsg(List<PkgResult> result) {
        String phoneMsg = I18nUtils.getMessage("CPH.MSG.SERVER");
        String causeMsg = I18nUtils.getMessage("CPH.MSG.CAUSE");
        String splitMsg = I18nUtils.getMessage("CPH.MSG.SPLIT");
        String connectMsg = I18nUtils.getMessage("CPH.MSG.CONNECT");
        return result.stream()
                .map(installResult -> phoneMsg + installResult.getId() + connectMsg + causeMsg + installResult.getErrorMsg())
                .collect(Collectors.joining(splitMsg));
    }

    private String genPhoneErrorMsg(List<PkgResult> result) {
        String phoneMsg = I18nUtils.getMessage("CPH.MSG.PHONE");
        String causeMsg = I18nUtils.getMessage("CPH.MSG.CAUSE");
        String splitMsg = I18nUtils.getMessage("CPH.MSG.SPLIT");
        String connectMsg = I18nUtils.getMessage("CPH.MSG.SPLIT");
        return result.stream()
                .map(installResult -> phoneMsg + installResult.getId() + connectMsg + causeMsg + installResult.getErrorMsg())
                .collect(Collectors.joining(splitMsg));
    }

    private String genServerPhoneErrorMsg(List<PkgResult> serverResult, List<PkgResult> phoneResult) {
        String errorMsg = genServerErrorMsg(serverResult);
        errorMsg += I18nUtils.getMessage("CPH.MSG.SPLIT");
        errorMsg += genPhoneErrorMsg(phoneResult);
        return errorMsg;
    }

    /**
     * 手机卸载共享应用
     *
     * @param phoneIds 手机ID
     * @param pkgName  应用名称
     */
    public void uninstallPkg(List<String> phoneIds, String pkgName) {
        List<PkgResult> result = pkgGateway.uninstallApk(phoneIds, pkgName);
        if (!result.isEmpty()) {
            throw new ApkUninstallException(genPhoneErrorMsg(result));
        }
    }

    /**
     * 手机卸载共享应用
     *
     * @param phoneIds 手机ID
     * @param pkgName  应用名称
     */
    public void uninstallSharePkg(List<String> phoneIds, String pkgName) {
        List<PkgResult> result = pkgGateway.uninstallTar(phoneIds, pkgName);
        if (!result.isEmpty()) {
            throw new ApkUninstallException(genPhoneErrorMsg(result));
        }
    }
}
